package br.com.documentos.model.util;

import java.security.MessageDigest;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import br.com.documentos.model.exceptions.CriptografiaException;

public class CriptografiaUtil {

	public static String encriptarSHA256(String senha) {
		try {
			MessageDigest digest = MessageDigest.getInstance("SHA-256");
			digest.update(senha.getBytes());
			BASE64Encoder encoder = new BASE64Encoder();
			return encoder.encode(digest.digest());
		} catch (Exception e) {
			throw new CriptografiaException(e);
		}
	}

	public static String encriptarMD5(String senha) {
		try {
			MessageDigest digest = MessageDigest.getInstance("MD5");
			digest.update(senha.getBytes());
			BASE64Encoder encoder = new BASE64Encoder();
			return encoder.encode(digest.digest());
		} catch (Exception e) {
			throw new CriptografiaException(e);
		}
	}

	private static final String METODO_AES = "AES";

	public static String encriptarComChave(String valor, String chave){

		try 
		{
			SecretKeySpec skeySpec = new SecretKeySpec(chave.getBytes(), METODO_AES);

			Cipher cipher = Cipher.getInstance(METODO_AES);
			cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
			byte[] encrypted = cipher.doFinal(valor.getBytes());

			return new BASE64Encoder().encode(encrypted);
		} 
		catch (Exception e) {
			throw new CriptografiaException(e);
		}
	}

	public static String decriptarComChave(String valor, String chave){

		byte[] decrypted = null;

		try {
			SecretKeySpec skeySpec = new SecretKeySpec(chave.getBytes(), METODO_AES);

			byte[] decoded = new BASE64Decoder().decodeBuffer(valor);

			Cipher cipher = Cipher.getInstance(METODO_AES);
			cipher.init(Cipher.DECRYPT_MODE, skeySpec);
			decrypted = cipher.doFinal(decoded);
		} 
		catch (Exception e) {
			throw new CriptografiaException(e);
		}

		return new String(decrypted);
	}
	
	public static String encriptaUrlComChave( String url, String chave ){
		
		int tamanhoChave = chave.length();
		int indexChave = 0;
		
		StringBuilder urlComChave = new StringBuilder();
		
		for( int i=0; i < url.length() ; i++ ){
			urlComChave.append( url.charAt(i) );

			if( indexChave < tamanhoChave ){
				urlComChave.append( chave.charAt(indexChave++) );
			}
		}
		
		StringBuilder urlEncriptada = new StringBuilder();
		
		for( byte b : urlComChave.toString().getBytes() ){
			urlEncriptada.append( String.format("%03d", b) );
		}
		
		return urlEncriptada.toString();
	}
	
	public static String descriptaUrlComChave( String url, String chave ){
		if( url == null || url.isEmpty() || (url.length() % 3) != 0 ){
			throw new CriptografiaException();
		}
		
		byte[] urlBytes = new byte[(url.length())/3];
		
		int indexResultado = 0; 
		
		for( int i=0 ; i < url.length(); i = i + 3 ){
			urlBytes[indexResultado++] = Byte.valueOf( url.substring(i,i+3) );
		}
		
		String urlDescriptadaComChave = new String(urlBytes);
		StringBuilder urlDescriptada = new StringBuilder();
		
		for( int i=0 ; i < urlDescriptadaComChave.length() ; i++ ){
			
			if( i < (chave.length()*2) && (i%2) != 0 ){
				continue;
			}
			
			urlDescriptada.append(urlDescriptadaComChave.charAt(i));
		}
		
		return urlDescriptada.toString();
	}
	
	public static String encriptaUrl( String url ){
		StringBuilder urlEncriptada = new StringBuilder();
		
		for( byte b : url.getBytes() ){
			urlEncriptada.append( String.format("%03d", b) );
		}
		
		return urlEncriptada.toString();
	}
	
	public static String descriptaUrl( String url ){
		if( url == null || url.isEmpty() || (url.length() % 3) != 0 ){
			throw new CriptografiaException();
		}
		
		byte[] urlBytes = new byte[(url.length())/3];
		
		int indexResultado = 0; 
		
		for( int i=0 ; i < url.length(); i = i + 3 ){
			urlBytes[indexResultado++] = Byte.valueOf( url.substring(i,i+3) );
		}
		
		return new String(urlBytes);
	}
	public static void main(String[] args) {
		
		String chave = "q1w2E#R$";
		String valor = "Esta senha é super dificil";
		
		String encr = encriptaUrl(valor);
		System.out.println( encr );
		
		System.out.println( descriptaUrl(encr) );
		
		
	}

}
